#ifndef _STORM_WDF_H_
#define _STORM_WDF_H_

#include "storm_wdm.h"
#include <usbdi.h>
#include <wdfusb.h>

/* Disable warnings about unitialized variables: */
#pragma warning(disable:4700)

/* Disable warnings about unreferenced formal parameters: */
#pragma warning(disable:4100)


// Reference counting
#ifdef WdfObjectReference
#undef WdfObjectReference
#endif
#define WdfObjectReference storm_WdfObjectReference
VOID
storm_WdfObjectReference(
  IN WDFOBJECT Handle
  );

#ifdef WdfObjectDereference
#undef WdfObjectDereference
#endif
#define WdfObjectDereference storm_WdfObjectDereference
VOID
storm_WdfObjectDereference(
  IN WDFOBJECT Handle
  );


// Spinlocks
#define WdfSpinLockCreate storm_WdfSpinLockCreate
NTSTATUS
storm_WdfSpinLockCreate(
  PWDF_OBJECT_ATTRIBUTES SpinLockAttributes,
  WDFSPINLOCK* SpinLock
  );

#define WdfSpinLockAcquire storm_WdfSpinLockAcquire
VOID
storm_WdfSpinLockAcquire(
  WDFSPINLOCK SpinLock
  );

#define WdfSpinLockRelease storm_WdfSpinLockRelease
VOID
storm_WdfSpinLockRelease(
  WDFSPINLOCK SpinLock
  );


// WDFREQUEST operations
#define WdfRequestCreate storm_WdfRequestCreate
NTSTATUS
storm_WdfRequestCreate(
  IN OPTIONAL PWDF_OBJECT_ATTRIBUTES RequestAttributes,
  IN OPTIONAL WDFIOTARGET IoTarget,
  OUT WDFREQUEST* Request
  );

#define WdfObjectCreate storm_WdfObjectCreate
NTSTATUS
storm_WdfObjectCreate(
  IN OPTIONAL PWDF_OBJECT_ATTRIBUTES Attributes,
  OUT WDFOBJECT* Object
  );

#define WdfObjectDelete storm_WdfObjectDelete
VOID
storm_WdfObjectDelete(
  WDFOBJECT Object
  );

#define WdfRequestIsCanceled storm_WdfRequestIsCanceled
BOOLEAN
storm_WdfRequestIsCanceled(
  IN WDFREQUEST Request
  );

#define WdfRequestCancelSentRequest storm_WdfRequestCancelSentRequest
BOOLEAN
storm_WdfRequestCancelSentRequest(
  IN WDFREQUEST Request
  );

#define WdfRequestSend storm_WdfRequestSend
BOOLEAN
storm_WdfRequestSend(
  WDFREQUEST Request,
  WDFIOTARGET Target,
  PWDF_REQUEST_SEND_OPTIONS RequestOptions
  );

#define WdfRequestGetStatus storm_WdfRequestGetStatus
NTSTATUS
storm_WdfRequestGetStatus(
  WDFREQUEST Request
  );

#define WdfRequestGetParameters storm_WdfRequestGetParameters
VOID
storm_WdfRequestGetParameters(
  IN WDFREQUEST Request,
  OUT PWDF_REQUEST_PARAMETERS Parameters
  );

#define WdfRequestGetFileObject storm_WdfRequestGetFileObject
WDFFILEOBJECT
storm_WdfRequestGetFileObject(
  IN WDFREQUEST Request
  );

#define WdfRequestComplete storm_WdfRequestComplete
VOID
storm_WdfRequestComplete(
  IN WDFREQUEST Request,
  IN NTSTATUS RequestStatus
  );

#define WdfRequestCompleteWithInformation storm_WdfRequestCompleteWithInformation
VOID
storm_WdfRequestCompleteWithInformation(
  WDFREQUEST Request,
  NTSTATUS Status,
  ULONG_PTR Information
  );

#define WdfRequestCompleteWithPriorityBoost storm_WdfRequestCompleteWithPriorityBoost
VOID
storm_WdfRequestCompleteWithPriorityBoost(
  IN WDFREQUEST Request,
  IN NTSTATUS Status,
  IN CCHAR PriorityBoost
  );


// Setting cancel and complete routines
#define WdfRequestMarkCancelable storm_WdfRequestMarkCancelable
VOID
storm_WdfRequestMarkCancelable(
  IN WDFREQUEST Request,
  IN PFN_WDF_REQUEST_CANCEL EvtRequestCancel
  );

#define WdfRequestMarkCancelableEx storm_WdfRequestMarkCancelableEx
NTSTATUS
storm_WdfRequestMarkCancelableEx(
  IN WDFREQUEST Request,
  IN PFN_WDF_REQUEST_CANCEL EvtRequestCancel
  );

#define WdfRequestUnmarkCancelable storm_WdfRequestUnmarkCancelable
NTSTATUS
storm_WdfRequestUnmarkCancelable(
  IN WDFREQUEST Request
  );

#define WdfRequestSetCompletionRoutine storm_WdfRequestSetCompletionRoutine
VOID
storm_WdfRequestSetCompletionRoutine(
  WDFREQUEST  Request,
  PFN_WDF_REQUEST_COMPLETION_ROUTINE  CompletionRoutine,
  WDFCONTEXT  CompletionContext
  );


// Collection
#define WdfCollectionCreate storm_WdfCollectionCreate
NTSTATUS
storm_WdfCollectionCreate(
  PWDF_OBJECT_ATTRIBUTES CollectionAttributes,
  WDFCOLLECTION *Collection
  );

#define WdfCollectionGetItem storm_WdfCollectionGetItem
WDFOBJECT
storm_WdfCollectionGetItem(
  IN WDFCOLLECTION Collection,
  IN ULONG Index
  );

#define WdfCollectionGetFirstItem storm_WdfCollectionGetFirstItem
WDFOBJECT
storm_WdfCollectionGetFirstItem(
  IN WDFCOLLECTION Collection
  );

#define WdfCollectionAdd storm_WdfCollectionAdd
NTSTATUS
storm_WdfCollectionAdd(
  WDFCOLLECTION Collection,
  WDFOBJECT Object
  );

#define WdfCollectionRemove storm_WdfCollectionRemove
VOID
storm_WdfCollectionRemove(
  WDFCOLLECTION Collection,
  WDFOBJECT Item
  );

#define WdfCollectionGetCount storm_WdfCollectionGetCount
ULONG
storm_WdfCollectionGetCount(
  WDFCOLLECTION Collection
  );


// WdmMdl
#define WdfRequestRetrieveInputWdmMdl storm_WdfRequestRetrieveInputWdmMdl
NTSTATUS
storm_WdfRequestRetrieveInputWdmMdl(
  IN WDFREQUEST Request,
  OUT PMDL* Mdl
  );

#define WdfRequestRetrieveOutputWdmMdl storm_WdfRequestRetrieveOutputWdmMdl
NTSTATUS
storm_WdfRequestRetrieveOutputWdmMdl(
  IN WDFREQUEST Request,
  OUT PMDL* Mdl
  );


// Buffers
#define WdfRequestRetrieveInputBuffer storm_WdfRequestRetrieveInputBuffer
NTSTATUS
storm_WdfRequestRetrieveInputBuffer(
  IN WDFREQUEST Request,
  IN size_t  MinimumRequiredSize,
  OUT PVOID* Buffer,
  OUT size_t* Length
  );

#define WdfRequestRetrieveOutputBuffer storm_WdfRequestRetrieveOutputBuffer
NTSTATUS
storm_WdfRequestRetrieveOutputBuffer(
  IN WDFREQUEST Request,
  IN size_t  MinimumRequiredSize,
  OUT PVOID* Buffer,
  OUT size_t* Length
  );

#define WdfMemoryGetBuffer storm_WdfMemoryGetBuffer
PVOID
storm_WdfMemoryGetBuffer(
  IN WDFMEMORY Memory,
  OUT OPTIONAL size_t* BufferSize
  );


// Device
#define WdfDeviceCreate storm_WdfDeviceCreate
NTSTATUS
storm_WdfDeviceCreate(
  IN OUT PWDFDEVICE_INIT* DeviceInit,
  IN OPTIONAL PWDF_OBJECT_ATTRIBUTES DeviceAttributes,
  OUT WDFDEVICE* Device
  );


// Queue
#define WdfDeviceGetDefaultQueue storm_WdfDeviceGetDefaultQueue
WDFQUEUE
storm_WdfDeviceGetDefaultQueue(
  IN WDFDEVICE Device
  );

#define WdfIoQueueCreate storm_WdfIoQueueCreate
NTSTATUS
storm_WdfIoQueueCreate(
  IN WDFDEVICE Device,
  IN PWDF_IO_QUEUE_CONFIG Config,
  IN OPTIONAL PWDF_OBJECT_ATTRIBUTES QueueAttributes,
  OUT WDFQUEUE* Queue
  );

#define WdfIoQueueGetDevice storm_WdfIoQueueGetDevice
WDFDEVICE
storm_WdfIoQueueGetDevice(
  IN WDFQUEUE Queue
  );

#define WdfRequestGetIoQueue storm_WdfRequestGetIoQueue
WDFQUEUE
storm_WdfRequestGetIoQueue(
  IN WDFREQUEST Request
  );


// Timer
#define WdfTimerGetParentObject storm_WdfTimerGetParentObject
WDFOBJECT
WdfTimerGetParentObject(
  IN WDFTIMER Timer
  );


// Pipe
#define WdfUsbTargetPipeGetInformation storm_WdfUsbTargetPipeGetInformation
VOID
storm_WdfUsbTargetPipeGetInformation(
  IN WDFUSBPIPE Pipe,
  OUT PWDF_USB_PIPE_INFORMATION PipeInformation
  );


// Utils
#define WdfObjectGetTypedContextWorker storm_WdfObjectGetTypedContextWorker
PVOID
storm_WdfObjectGetTypedContextWorker(
  WDFOBJECT Handle,
  PCWDF_OBJECT_CONTEXT_TYPE_INFO TypeInfo
  );

#define WdfObjectContextGetObject storm_WdfObjectContextGetObject
WDFOBJECT
storm_WdfObjectContextGetObject(
  IN PVOID ContextPointer
  );

#define WdfMemoryCreate storm_WdfMemoryCreate
NTSTATUS
storm_WdfMemoryCreate(
  PWDF_OBJECT_ATTRIBUTES Attributes,
  IN POOL_TYPE PoolType,
  IN OPTIONAL ULONG PoolTag,
  IN size_t BufferSize,
  OUT WDFMEMORY* Memory,
  OUT OPTIONAL PVOID* Buffer
  );

#define WDF_REQUEST_PARAMETERS_INIT storm_WDF_REQUEST_PARAMETERS_INIT
VOID
storm_WDF_REQUEST_PARAMETERS_INIT(
  OUT PWDF_REQUEST_PARAMETERS Parameters
  );

#endif

